#include "uart.h"

#include <stdarg.h>
#include <stdio.h>
#include "../system/system.h"



void Uart_Initial_g(uint32_t baudrate)
{    
    
    /**    
         Set the UART1 module to the options selected in the user interface.
         Make sure to set LAT bit corresponding to TxPin as high before UART initialization
    */
    // STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; URXINV disabled; UEN TX_RX; 
    //U2MODE = (0x8008 & ~(1<<15));  // disabling UARTEN bit   
    U2MODEbits.UARTEN = 0; //bit15, uart 1-enable,0-disable
    U2MODEbits.USIDL = 0; //bit13, stop in idle mode
    U2MODEbits.IREN = 0; //bit12,IrDA enable
    U2MODEbits.RTSMD = 0; //bit11,_UxRTS pin mode,0-single mode,1-flow control mode
    U2MODEbits.UEN = 0; //bit9:8,UARTx enable bit,00-Tx&Rx,01-Tx&Rx&_UxTRS,10-Tx&Rx&_UxCTS&_UxRTS,11-Tx&Rx&_BCLKx
    U2MODEbits.WAKE = 0; //bit7,wake up in sleep mode,0-disable,1-enable,uart can not notice first char after waking up;
    U2MODEbits.LPBACK = 0; //bit6,loop back,0-disable,1-enable
    U2MODEbits.ABAUD = 0; //bit5,auto baudrate,1-auto,0-disable
    U2MODEbits.URXINV = 0; //bit4, receive reverse
    U2MODEbits.BRGH = 1; //bit3,0-standard mode,1-high speed
    U2MODEbits.PDSEL = 00; //bit2:1,parity and datalength,00-8bitN,01-8bitEven,10-8bitOdd,11-9bitN
    U2MODEbits.STSEL = 0; //bit0,stop bit,0-1bit,1-2bits
    // UTXISEL0 TX_ONE_CHAR; UTXINV disabled; OERR NO_ERROR_cleared; URXISEL RX_ONE_CHAR; UTXBRK COMPLETED; UTXEN disabled; ADDEN disabled; 
    U2STA = 0x0;
    // BRGH=0 (Fosc/2/16/baudrate -1);
    // BRGH=1 (systemFrequency/2/4/baudrate - 1)
    U2BRG = (uint16_t)((U2MODEbits.BRGH==0)?(SYSTEM_FOSC/2/16/baudrate -1):(SYSTEM_FOSC/2/4/baudrate -1));
    
    U2MODEbits.UARTEN = 1;  // enabling UARTEN bit
    U2STAbits.UTXEN = 1; 
}

void Uart_WriteByte_g(uint8_t byte)
{
    while(U2STAbits.UTXBF == 1)
    {
        
    }

    U2TXREG = byte;    // Write the data byte to the USART.
    
}

uint8_t Uart_ReadByte(void)
{
    while(!(U2STAbits.URXDA == 1))
    {
        
    }

    if ((U2STAbits.OERR == 1))
    {
        U2STAbits.OERR = 0;
    }

    return U2RXREG;
}

void Uart_WriteBytes_g(uint8_t *arrayBytes,uint8_t length)
{
    uint8_t i =0 ;
    for(i=0;i<length;i++)
    {
        Uart_WriteByte_g(*arrayBytes);
        arrayBytes++;
    }
}

UART_STATUS UART_StatusGet (void)
{
    return U2STA;
}

void Uart_WriteString(char *string)
{
    while(*string!='\0')
    {  
        if(*string=='\n')
        {
            Uart_WriteByte_g(0x0D);
            Uart_WriteByte_g(0x0A);
        }
        else
            Uart_WriteByte_g(*string);  
        string++;  
    }  
}

void Uart_Printf_g(const char *fmt,...)
{
    va_list ap;  
    char string[1024];  
    va_start(ap,fmt);  
    vsprintf(string,fmt,ap);
    Uart_WriteString(string);  
    va_end(ap); 
}

